package com.lijinjiang.model.tree;

import com.lijinjiang.exception.ConnectException;
import com.lijinjiang.util.ImageUtil;
import com.lijinjiang.view.DBDialog;

import javax.swing.*;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName ServerConnection
 * @Description 服务器连接
 * @Author Li
 * @Date 2022/8/14 22:13
 * @ModifyDate 2022/8/14 22:13
 * @Version 1.0
 */
public class ServerConnection extends ConnectionNode {
    // 连接名称
    private String name;
    // 连接ip
    private String host;
    // 连接端口
    private String port;
    // 用户
    private String user;
    // 密码
    private String password;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPort() {
        return port;
    }

    public void setPort(String port) {
        this.port = port;
    }

    /**
     * 全参构造器
     * @param name
     * @param host
     * @param user
     * @param password
     * @param port
     */
    public ServerConnection(String name, String host, String port, String user, String password) {
        this.name = name;
        this.host = host;
        this.user = user;
        this.password = password;
        this.port = port;
    }

    /**
     * 获取连接
     * @return
     */
    @Override
    public Connection connect() {
        // serverConnection 在本类的实例中只有一个实例
        if (super.connection != null) {
            return super.connection;
        }
        try {
            Connection conn = createConnection("");
            super.connection = conn;
            return conn;
        } catch (SQLException e) {
            throw new ConnectException(e.getErrorCode() + " - " + e.getMessage());
        }
    }

    /**
     * 创建连接
     * @param database
     * @return
     * @throws Exception
     */
    public Connection createConnection(String database) throws SQLException {
        String url = "jdbc:mysql://" + this.host + ":" + this.port + "/";
        Connection conn = DriverManager.getConnection(url + database +
                "?useSSL=false", this.user, this.password);
        return conn;
    }

    /**
     * 获取一个服务器连接下的所有的数据库
     * @return
     */
    public List<Database> getDatabases() {
        List<Database> list = new ArrayList<>();
        try {
            // 获得一个连接下面的所有数据库
            Statement stmt = getStatement();
            ResultSet rs = stmt.executeQuery("show databases");
            while (rs.next()) {
                String databaseName = rs.getString("Database");
                Database db = new Database(databaseName, this);
                list.add(db);
            }
            rs.close();
            return list;
        } catch (Exception e) {
            return list;
        }
    }

    /**
     * 获取一个服务器连接下的所有的字符集
     * @return
     */
    public List<String> getCharsets() {
        List<String> list = new ArrayList<>();
        try {
            // 获得一个连接下面的所有数据库
            Statement stmt = getStatement();
            ResultSet rs = stmt.executeQuery("show character set");
            while (rs.next()) {
                String charset = rs.getString("Charset");
                list.add(charset);
            }
            rs.close();
            return list;
        } catch (Exception e) {
            return list;
        }
    }

    /**
     * 获取一个服务器连接下的所有的排序规则
     * @return
     */
    public List<String> getCollations(String charset) {
        List<String> list = new ArrayList<>();
        try {
            // 获得一个连接下面的所有数据库
            Statement stmt = getStatement();
            ResultSet rs = stmt.executeQuery("show collation where Charset = '" + charset + "'");
            while (rs.next()) {
                String collation = rs.getString("Collation");
                list.add(collation);
            }
            rs.close();
            return list;
        } catch (Exception e) {
            return list;
        }
    }

    /**
     * 创建一个数据库，并返回其排序位置的索引
     * @param dialog
     * @param database
     * @return
     */
    public int createDatabase(DBDialog dialog, Database database) {
        if (database != null) {
            String name = database.getDbName();
            if (name != null && !"".equalsIgnoreCase(name)) {
                String sql = "CREATE DATABASE " + name + " DEFAULT CHARACTER SET " + database.getCharset() + " DEFAULT COLLATE " + database.getCollation();
                try {
                    Statement stmt = getStatement();
                    stmt.executeUpdate(sql);
                    dialog.dispose();
                    List<Database> dbs = getDatabases();
                    for (int i = 0; i < dbs.size(); i++) {
                        if (name.equalsIgnoreCase(dbs.get(i).getDbName())) {
                            return i;
                        }
                    }
                    return -1;
                } catch (Exception e) {
                    JOptionPane.showMessageDialog(dialog, e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                    return -1;
                }
            } else {
                return -1;
            }
        } else {
            return -1;
        }
    }

    /**
     * 删除数据库
     * @param db
     */
    public void dropDatabase(Database db) {
        String sql = "DROP DATABASE " + db.getDbName();
        try {
            Statement stmt = getStatement();
            stmt.executeUpdate(sql);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    // 如果服务器已经连接，则使用现成的连接创建Statement，没有则重新创建连接
    public Statement getStatement() throws SQLException {
        if (super.connection != null) {
            return super.connection.createStatement();
        }
        Connection conn = createConnection("");
        return conn.createStatement();
    }

    // 重写获取图标方法，根据连接状态获取图标
    @Override
    public Icon getIcon() {
        if (super.connection == null) return ImageUtil.CONNECTION_CLOSE_ICON;
        else return ImageUtil.CONNECTION_OPEN_ICON;
    }

    // 重写 toString 方法，这样在树节点会直接显示连接的名称
    @Override
    public String toString() {
        return this.getName();
    }
}
